home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianLights.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  18KB  |  802 lines

  1. /*ScianLights.c
  2.   Lights
  3.   Eric Pepke
  4.   May 21, 1991
  5. */
  6.  
  7. #include "Scian.h"
  8. #include "ScianTypes.h"
  9. #include "ScianColors.h"
  10. #include "ScianLists.h"
  11. #include "ScianArrays.h"
  12. #include "ScianWindows.h"
  13. #include "ScianSpaces.h"
  14. #include "ScianDraw.h"
  15. #include "ScianObjWindows.h"
  16. #include "ScianVisWindows.h"
  17. #include "ScianVisObjects.h"
  18. #include "ScianIcons.h"
  19. #include "ScianIDs.h"
  20. #include "ScianControls.h"
  21. #include "ScianButtons.h"
  22. #include "ScianErrors.h"
  23. #include "ScianDialogs.h"
  24. #include "ScianSliders.h"
  25. #include "ScianTextBoxes.h"
  26. #include "ScianStyle.h"
  27. #include "ScianComplexControls.h"
  28. #include "ScianLights.h"
  29. #include "ScianMethods.h"
  30. #include "ScianScripts.h"
  31. #include "ScianEvents.h"
  32. #include "ScianObjFunctions.h"
  33. #include "ScianSymbols.h"
  34. #include "ScianFontSystem.h"
  35.  
  36. ObjPtr lightClass;            /*Class of individual light*/
  37. int lightsNum = 0;
  38. ObjPtr commonLights = NULLOBJ;    
  39. Bool lastTwoSided = false;        /*Last change to twoSided*/
  40. int nTotalLights = 0;
  41.  
  42. #define TOTALLIGHTS    8        /*Total number of possible lights*/
  43. #define NLIGHTS        2        /*Number of lights available by default*/
  44.  
  45. lightSpec defLights[] =
  46.     {
  47.     {(M_PI_4 * 1.2), M_PI_4, {1.0, 1.0, 1.0}, 1.0, false},
  48.     /*{M_PI_2, M_PI_4, {0.7, 1.0, 1.0}, 0.5, false},*/
  49.     {-M_PI_4, - 0.7 * M_PI_4, {0.7, 1.0, 1.0}, 0.5, false},
  50.     {M_PI, M_PI_4, {1.0, 0.0, 0.5}, 0.2, true},
  51.     {0.0, M_PI_2, {1.0, 1.0, 0.6}, 0.3, true}
  52.     };
  53.  
  54. #ifdef GRAPHICS
  55. /*Don't change this without checking references*/
  56. float lightModel[] = {
  57.             AMBIENT, 0.2, 0.2, 0.2,
  58. #ifdef TWOSIDE
  59.             TWOSIDE, 0.0,
  60. #endif
  61.             LMNULL};
  62. #endif
  63.  
  64. #ifdef PROTO
  65. void TwoSided(Bool whether)
  66. #else
  67. void TwoSided(whether)
  68. Bool whether;
  69. #endif
  70. /*Goes to two sided lighting on whether*/
  71. {
  72. #ifdef GRAPHICS
  73.     {
  74.     if (whether != lastTwoSided)
  75.     {
  76.         int k;
  77.         lastTwoSided = whether;
  78.         if (whether)
  79.         {
  80.         /*Bind all the reverse lights*/
  81.         for (k = 0; k < nTotalLights; ++k)
  82.         {
  83.             if (rgbp)
  84.             {
  85.             lmbind(LIGHT0 + k + nTotalLights, k * 2 + 2);
  86.             }
  87.         }
  88.         }
  89.         else
  90.         {
  91.         /*Unbind all the reverse lights*/
  92.         for (k = 0; k < nTotalLights; ++k)
  93.         {
  94.             if (rgbp)
  95.             {
  96.                 lmbind(LIGHT0 + k + nTotalLights, 0);
  97.             }
  98.         }
  99.         }
  100.     }
  101.     }
  102. #endif
  103. }
  104.  
  105. #ifdef PROTO
  106. void StartLights(ObjPtr space, ObjPtr lights, Bool twoSided)
  107. #else
  108. void StartLights(space, lights, twoSided)
  109. ObjPtr space, lights;
  110. Bool twoSided;
  111. #endif
  112. /*Starts the lights*/
  113. {
  114.     ThingListPtr runner;
  115.     int k;
  116.  
  117. #ifdef GRAPHICS
  118.     if (rgbp)
  119.     {
  120.     lmbind(LMODEL, 1);
  121.     }
  122. #endif
  123.  
  124.     runner = LISTOF(lights);
  125.     k = 0;
  126.     while (runner)
  127.     {
  128.     ObjPtr light;
  129.     ObjPtr var;
  130.     real brightness;
  131.     real baseColor[3];
  132.     real location[3];
  133. #ifdef GRAPHICS
  134.     float tempLight[50];
  135.     float *lightPtr;
  136. #endif
  137.  
  138.     light = runner -> thing;
  139.  
  140.     if (k < TOTALLIGHTS && !GetPredicate(runner -> thing, HIDDEN))
  141.     {
  142.     
  143.         var = GetVar(light, BRIGHTNESS);
  144.         if (var && IsReal(var))
  145.         {
  146.         brightness = GetReal(var);
  147.         }
  148.         else
  149.         {
  150.         brightness = 1.0;
  151.         }
  152.         var = GetVar(light, BASECOLOR);
  153.         if (var)
  154.         {
  155.         Array2CArray(baseColor, var);
  156.         }
  157.         else
  158.         {
  159.         baseColor[0] = 1.0;
  160.         baseColor[1] = 1.0;
  161.         baseColor[2] = 1.0;
  162.         }
  163.         var = GetFixedArrayVar("StartLights", light, LOCATION, 1, 3L);
  164.         if (!var)
  165.         {
  166.         return;
  167.         }
  168.         Array2CArray(location, var);
  169.  
  170. #ifdef GRAPHICS
  171.         lightPtr = tempLight;
  172.         *lightPtr++ = POSITION;
  173.         *lightPtr++ = location[0];
  174.         *lightPtr++ = location[1];
  175.         *lightPtr++ = location[2];
  176.         *lightPtr++ = 0.0;
  177.         *lightPtr++ = LCOLOR;
  178.         *lightPtr++ = baseColor[0] * brightness;
  179.         *lightPtr++ = baseColor[1] * brightness;
  180.         *lightPtr++ = baseColor[2] * brightness;
  181.         *lightPtr++ = LMNULL; 
  182.  
  183.         if (rgbp)
  184.         {
  185.             lmdef(DEFLIGHT, k * 2 + 1, 0, tempLight);
  186.  
  187.         lmbind(LIGHT0 + k, k * 2 + 1);
  188.         }
  189.  
  190.         {
  191.         /*Make the reverse light*/
  192.         lightPtr = tempLight;
  193.         *lightPtr++ = POSITION;
  194.         *lightPtr++ = -location[0];
  195.         *lightPtr++ = -location[1];
  196.         *lightPtr++ = -location[2];
  197.         *lightPtr++ = 0.0;
  198.         *lightPtr++ = LCOLOR;
  199.         *lightPtr++ = baseColor[0] * brightness;
  200.         *lightPtr++ = baseColor[1] * brightness;
  201.         *lightPtr++ = baseColor[2] * brightness;
  202.         *lightPtr++ = LMNULL; 
  203.         if (rgbp)
  204.         {
  205.             lmdef(DEFLIGHT, k * 2 + 2, 0, tempLight);
  206.         }
  207.         }
  208. #endif
  209.         ++k;
  210.     }
  211.     runner = runner -> next;
  212.     }
  213.     nTotalLights = k;
  214. }
  215.  
  216. void StopLights(space)
  217. ObjPtr space;
  218. /*Stops lights in space*/
  219. {
  220.     int k;
  221.  
  222. #ifdef GRAPHICS
  223.     for (k = 0; k < TOTALLIGHTS; ++k)
  224.     {
  225.     if (rgbp)
  226.     {
  227.         lmbind(LIGHT0 + k, 0);
  228.     }
  229.     }
  230.  
  231.     if (rgbp)
  232.     {
  233.     lmbind(LMODEL, 0);
  234.     }
  235. #endif
  236. }
  237.  
  238. ObjPtr NewLight(k)
  239. int k;
  240. /*Returns a new light with default definition k*/
  241. {
  242.     ObjPtr light;
  243.     ObjPtr baseColor;
  244.     ObjPtr name;
  245.     ObjPtr loc;
  246.     real *locPtr;
  247.  
  248.     light = NewObject(lightClass, 0);
  249.  
  250.     /*Set light position*/
  251.     loc = NewRealArray(1, 3L);
  252.     locPtr = ArrayMeat(loc);
  253.     *locPtr++ = rcos(defLights[k] . theta) * rcos(defLights[k] . phi);
  254.     *locPtr++ = rsin(defLights[k] . theta) * rcos(defLights[k] . phi);
  255.     *locPtr++ = rsin(defLights[k] . phi);
  256.     SetVar(light, LOCATION, loc);
  257.  
  258.     /*Set light color*/
  259.     baseColor = NewRealArray(1, 3L);
  260.     CArray2Array(baseColor, defLights[k] . baseColor);
  261.     SetVar(light, BASECOLOR, baseColor);
  262.  
  263.     /*Set light brightness*/
  264.     SetVar(light, BRIGHTNESS, NewReal(defLights[k] . brightness));
  265.  
  266.     /*Set whether the light is enabled or not*/
  267.     SetVar(light, HIDDEN, NewInt(defLights[k] . enabled));
  268.     
  269.     name = GetVar(lightClass, NAME);
  270.     if (name)
  271.     {
  272.         sprintf(tempStr, "%s %d", GetString(name), ++lightsNum);
  273.         }
  274.     else
  275.     {
  276.         sprintf(tempStr, "Light %d", ++lightsNum);
  277.     }
  278.     name = NewString(tempStr);
  279.     SetVar(light, NAME, name);
  280.     SetVar(light, SPACES, NewList());
  281.  
  282.     return light;
  283. }
  284.  
  285. ObjPtr NewLights()
  286. /*Returns a new list of lights*/
  287. {
  288.     ObjPtr lights;
  289.     int k;
  290.  
  291.     if (oneLights)
  292.     {
  293.     if (commonLights) return commonLights;
  294.     }
  295.  
  296.     lights = NewList();
  297.     for (k = 0; k < NLIGHTS; ++k)
  298.     {
  299.     ObjPtr light;
  300.  
  301.     light = NewLight(k);
  302.  
  303.     /*Set the light's parent*/
  304.     SetVar(light, PARENT, lights);
  305.  
  306.     PostfixList(lights, light);
  307.     }
  308.  
  309.     return lights;
  310. }
  311.  
  312. static ObjPtr CloneLight(light)
  313. ObjPtr light;
  314. /*Clones a light light*/
  315. {
  316.     ObjPtr newLight;
  317.  
  318.     newLight = NewLight(0);
  319.     CopyVar(newLight, light, LOCATION);
  320.     CopyVar(newLight, light, BASECOLOR);
  321.     CopyVar(newLight, light, BRIGHTNESS);
  322.     CopyVar(newLight, light, HIDDEN);
  323.  
  324.     return newLight;
  325. }
  326.  
  327. static ObjPtr BindLightToSpace(light, space)
  328. ObjPtr light, space;
  329. /*Makes space know about a light.*/
  330. {
  331.     ObjPtr lightsList;
  332.  
  333.     lightsList = GetVar(space, LIGHTS);
  334.     if (!lightsList)
  335.     {
  336.     lightsList = NewList();
  337.     SetVar(space, LIGHTS, lightsList);
  338.     }
  339.     
  340.     PrefixList(lightsList, light);
  341.     SetVar(light, PARENT, space);
  342.  
  343.     if (ListCount(lightsList) > TOTALLIGHTS)
  344.     {
  345.     char errmes[256];
  346.     sprintf(errmes, "Only %d lights can be shown.\n", TOTALLIGHTS);
  347.     ReportError("BindLightToSpace", errmes); 
  348.     }
  349.     return ObjTrue;
  350. }
  351.  
  352. static ObjPtr HideLight(light)
  353. ObjPtr light;
  354. /*Hides a light*/
  355. {
  356.     SetVar(light, HIDDEN, ObjTrue);
  357.     ImInvalid(light);
  358.     return ObjTrue;
  359. }
  360.  
  361. static ObjPtr ShowLight(light)
  362. ObjPtr light;
  363. /*Shows a light*/
  364. {
  365.     SetVar(light, HIDDEN, ObjFalse);
  366.     ImInvalid(light);
  367.     return ObjTrue;
  368. }
  369.  
  370.  
  371. static ObjPtr lightForRGB;
  372.  
  373. static void LightRGB(visWindow)
  374. WinInfoPtr visWindow;
  375. /*Sends a deferred message to visWindow if it has lightForRGB*/
  376. {
  377.     ObjPtr space;
  378.     ObjPtr lights;
  379.  
  380.     space = FindSpace(visWindow);
  381.     if (space)
  382.     {
  383.     lights = GetVar(space, LIGHTS);
  384.     if (lights)
  385.     {
  386.         ThingListPtr runner;
  387.  
  388.         runner = LISTOF(lights);
  389.         while (runner)
  390.         {
  391.         if (runner -> thing == lightForRGB)
  392.         {
  393.             DeferMessage((ObjPtr) visWindow, SETRGBMESSAGE);
  394.             return;
  395.         }
  396.         runner = runner -> next;
  397.         }
  398.     }
  399.     }
  400. }
  401.  
  402. static ObjPtr ShowLightControls(object, windowName)
  403. ObjPtr object;
  404. char *windowName;
  405. /*Makes a new control window to control light*/
  406. {
  407.     WinInfoPtr controlWindow;
  408.     ObjPtr var;
  409.     ObjPtr panel;
  410.     ObjPtr contents;
  411.     ObjPtr lights;
  412.     ThingListPtr runner;
  413.     ObjPtr firstIcon = 0;
  414.     WinInfoPtr dialogExists;
  415.     int k;
  416.  
  417.     dialogExists = DialogExists((WinInfoPtr) object, NewString("Controls"));
  418.     controlWindow = GetDialog((WinInfoPtr) object, NewString("Controls"), windowName, 
  419.     LWINWIDTH, LWINHEIGHT, LWINWIDTH, LWINHEIGHT, WINUI + WINFIXEDSIZE);
  420.     SetVar((ObjPtr) controlWindow, HELPSTRING,
  421.     NewString("This window shows controls for a light source at infinity."));
  422.  
  423. #ifdef GRAPHICS
  424.     if (hasRGB)
  425.     {
  426.     lightForRGB = object;
  427.     ForAllVisWindows(LightRGB);
  428.     }
  429. #endif
  430.  
  431.     if (!dialogExists)
  432.     {
  433.     ObjPtr control, checkBox, corral, sw, textBox, slider, icon, colorObj;
  434.     ObjPtr var, button;
  435.     int width, left, right, bottom, top, cellHeight, m1, m2;
  436.  
  437.     SetVar((ObjPtr) controlWindow, REPOBJ, object);
  438.  
  439.     /*Add in a panel*/
  440.     panel = NewPanel(greyPanelClass, 0, LWINWIDTH, 0, LWINHEIGHT);
  441.     if (!panel)
  442.     {
  443.         return ObjFalse;
  444.     }
  445.     contents = GetVar((ObjPtr) controlWindow, CONTENTS);
  446.     PrefixList(contents, panel);
  447.     SetVar(panel, PARENT, (ObjPtr) controlWindow);
  448.  
  449.     contents = NewList();
  450.     SetVar(panel, CONTENTS, contents);
  451.  
  452.     width = LWINWIDTH - 2 * CORRALBORDER;
  453.     left = MAJORBORDER;
  454.  
  455.     cellHeight = COLORWHEELWIDTH;
  456.  
  457.     /*Precalculate the midlines for convenience*/
  458.     m1 = LWINHEIGHT - MAJORBORDER - cellHeight / 2;
  459.  
  460.     left += COLORWHEELWIDTH + MAJORBORDER;
  461.  
  462.     /*Create the color control*/
  463.     control = NewColorWheel(left - COLORWHEELWIDTH - MAJORBORDER, left - MAJORBORDER, 
  464.             m1 - COLORWHEELWIDTH / 2,
  465.             m1 + COLORWHEELWIDTH / 2, "Color");
  466.     SetVar(control, HELPSTRING, NewString("This color wheel controls the base color of a light.  \
  467. It will only have an effect if the window containing the light is in full color mode."));
  468.     PrefixList(contents, control);
  469.     SetVar(control, PARENT, panel);
  470.     AssocColorControlWithVar(control, object, BASECOLOR);
  471.  
  472.     var = GetFixedArrayVar("ShowLightControls", object, BASECOLOR, 1, 3L);
  473.     if (!var)
  474.     {
  475.         real *baseColor;
  476.  
  477.         var = NewRealArray(1, 3L);
  478.         baseColor = ELEMENTS(var);
  479.  
  480.         baseColor[0] = 1.0;
  481.         baseColor[1] = 1.0;
  482.         baseColor[2] = 1.0;
  483.         SetVar(object, BASECOLOR, var);
  484.     }
  485.  
  486.     /*Create the text box*/
  487.     textBox = NewTextBox(left - COLORWHEELWIDTH - MAJORBORDER - 30, left - MAJORBORDER + 30, 
  488.              m1 - cellHeight / 2 - TEXTBOXSEP - TEXTBOXHEIGHT,
  489.              m1 - cellHeight / 2 - TEXTBOXSEP,
  490.              0, "Color Text", "Color");
  491.     PrefixList(contents, textBox);
  492.     SetVar(textBox, PARENT, panel);
  493.     SetTextAlign(textBox, CENTERALIGN);
  494.  
  495.     left += MAJORBORDER;
  496.  
  497.     /*Create the brightness slider*/
  498.     var = GetRealVar("ShowLightControls", object, BRIGHTNESS);
  499.     if (!var)
  500.     {
  501.         SetVar(object, BRIGHTNESS, NewReal(1.0));
  502.     }
  503.     slider = NewSlider(left, left + SLIDERWIDTH, 
  504.                m1 - cellHeight / 2, m1 + cellHeight / 2,
  505.                PLAIN, "Brightness");
  506.     SetVar(slider, HELPSTRING, NewString("This slider controls the brightness \
  507. of the light.  It will only have an effect if the window containing the light is in full color mode."));
  508.     if (!slider)
  509.     {
  510.         return ObjFalse;
  511.     }
  512.     PrefixList(contents, slider);
  513.     SetVar(slider, PARENT, panel);
  514.     SetSliderRange(slider, 1.0, 0.0, 0.0);
  515.     AssocDirectControlWithVar(slider, object, BRIGHTNESS);
  516.  
  517.     /*Create the brightness text box*/
  518.     textBox = NewTextBox(left - MAJORBORDER - MINORBORDER, left + SLIDERWIDTH + MINORBORDER + MAJORBORDER, 
  519.              m1 - cellHeight / 2 - TEXTBOXSEP - TEXTBOXHEIGHT,
  520.              m1 - cellHeight / 2 - TEXTBOXSEP,
  521.              0, "Brightness Text", "Brightness");
  522.     PrefixList(contents, textBox);
  523.     SetVar(textBox, PARENT, panel);
  524.     SetTextAlign(textBox, CENTERALIGN);
  525.     }
  526.  
  527.     return (ObjPtr) controlWindow;
  528. }
  529.  
  530. #define LIGHTDSPSTEP 0.1  /*Step to display outward for lights*/
  531. static real globalLightRadius;
  532. ObjPtr DrawLight(light)
  533. ObjPtr light;
  534. /*Draws a light in a space*/
  535. {
  536.     float lightrad = 1.0;
  537.     if (IsSelected(light))
  538.     {
  539.         ObjPtr var;
  540.         real brightness;
  541.         real baseColor[3];
  542.         real location[3];
  543.         float clr[3];
  544.         real azimuth;
  545.         real xyrange;
  546.         real elevation;
  547.     
  548.         lightrad += LIGHTDSPSTEP;
  549.  
  550.         var = GetVar(light, BRIGHTNESS);
  551.         if (var && IsReal(var))
  552.         {
  553.         brightness = GetReal(var);
  554.         }
  555.         else
  556.         {
  557.         brightness = 1.0;
  558.         }
  559.         var = GetVar(light, BASECOLOR);
  560.         if (var)
  561.         {
  562.         Array2CArray(baseColor, var);
  563.         }
  564.         else
  565.         {
  566.         baseColor[0] = 1.0;
  567.         baseColor[1] = 1.0;
  568.         baseColor[2] = 1.0;
  569.         }
  570.         var = GetFixedArrayVar("DrawLights", light, LOCATION, 1, 3L);
  571.         if (!var)
  572.         {
  573.         return;
  574.         }
  575.         Array2CArray(location, var);
  576.  
  577.         /*Calculate the azimuth*/
  578.         if (location[0] == 0.0 && location[1] == 0.0)
  579.         {
  580.         azimuth = 0.0;
  581.         }
  582.         else
  583.         {
  584.         azimuth = atan2(location[1], location[0]);
  585.         }
  586.  
  587.         /*Calculate the xyrange and elevation*/
  588.         xyrange = (float) sqrt(location[0] * location[0] + location[1] * location[1]);
  589.         elevation = atan2(location[2], xyrange);
  590.         if (elevation >= M_PI) elevation -= 2 * M_PI;
  591.  
  592.         SetLineWidth(2);
  593.         SetUIColor(UIGRAY50);
  594.  
  595.         /*Draw the horizon circle*/
  596.         {
  597.         NudgeFarther();
  598.         NudgeFarther();
  599. #ifdef GRAPHICS
  600.         circ(0.0, 0.0, globalLightRadius);
  601. #endif
  602.         NudgeCloser();
  603.         NudgeCloser();
  604.         }
  605.  
  606.         /*Draw the X space line*/
  607.         SetUIColor(UIWHITE);
  608.         DrawSpaceLine(0.0, 0.0, 0.0, lightrad * globalLightRadius, 0.0, 0.0);
  609.  
  610.         /*Choose a color for subsequent stuff*/
  611. #ifdef GRAPHICS
  612.         clr[0] = baseColor[0] * (brightness * 0.8 + 0.2);
  613.         clr[1] = baseColor[1] * (brightness * 0.8 + 0.2);
  614.         clr[2] = baseColor[2] * (brightness * 0.8 + 0.2);
  615.         if (rgbp)
  616.         {
  617.         c3f(clr);
  618.         }
  619.         else
  620.         {
  621.         color(uiColorIndex[ClosestUIColor(clr)]);
  622.         }
  623. #endif
  624.  
  625.         /*Draw the azimuth measurement*/
  626.         sprintf(tempStr, "%4.0f deg.", (float) azimuth * 180.0 / M_PI);
  627.         SetUIFont(UIBOLDLARGEFONT);
  628.         DrawSpaceString((lightrad + 0.05) * globalLightRadius * rcos(azimuth * 0.5),
  629.                 (lightrad + 0.05) * globalLightRadius * rsin(azimuth * 0.5),
  630.                 0.0,
  631.                 tempStr);
  632.  
  633. #ifdef GRAPHICS
  634.         /*Draw the azimuth circle*/
  635.         if (azimuth < 0.0)
  636.         {
  637.         arc(0.0, 0.0, lightrad * globalLightRadius, azimuth * 1800.0 / M_PI, 0);
  638.         }
  639.         else
  640.         {
  641.         arc(0.0, 0.0, lightrad * globalLightRadius, 0, azimuth * 1800.0 / M_PI);
  642.         }
  643. #endif
  644.  
  645.         /*Draw the azimuth line*/
  646.         DrawSpaceLine(0.0, 0.0, 0.0, lightrad * globalLightRadius * rcos(azimuth), lightrad * globalLightRadius * sin(azimuth), 0.0);
  647.  
  648. #ifdef GRAPHICS
  649.         /*Draw the elevation arc*/
  650.         pushmatrix();
  651.         rotate(900, 'x');
  652.         rot(azimuth * 180.0 / M_PI, 'y');
  653.         if (elevation < 0.0)
  654.         {
  655.         arc(0.0, 0.0, lightrad * globalLightRadius, elevation * 1800.0 / M_PI, 0);
  656.         }
  657.         else
  658.         {
  659.         arc(0.0, 0.0, lightrad * globalLightRadius, 0, elevation * 1800.0 / M_PI);
  660.         }
  661. #endif
  662.  
  663.         /*Draw the elevation measurement*/
  664.         sprintf(tempStr, "%4.0f deg.", (float) elevation * 180.0 / M_PI);
  665.         SetUIFont(UIBOLDLARGEFONT);
  666.         DrawSpaceString((lightrad + 0.05) * globalLightRadius * rcos(elevation * 0.5),
  667.                 (lightrad + 0.05) * globalLightRadius * sin(elevation * 0.5),
  668.                 0.0,
  669.                 tempStr);
  670.  
  671. #ifdef GRAPHICS
  672.         popmatrix();
  673. #endif
  674.  
  675.         SetLineWidth(3);
  676.  
  677.         DrawSpaceLine(0.0, 0.0, 0.0, 30.0 * location[0],
  678.          30.0 * location[1],
  679.          30.0 * location[2]);
  680.         SetLineWidth(1);
  681.     }
  682.  
  683. }    
  684.  
  685. #ifdef PROTO
  686. void DrawLights(ObjPtr space, ObjPtr lights, int action, real radius)
  687. #else
  688. void DrawLights(space, lights, action, radius)
  689. ObjPtr space, lights;
  690. int action;
  691. real radius;
  692. #endif
  693. /*Draw lights in space if they want to be displayed
  694.   Action is DRAWSPACE, PICKSPACE, etc.
  695.   Radius is radius of sphere in center area*/
  696. {
  697. #ifdef GRAPHICS
  698.     ThingListPtr runner;
  699.  
  700.     zbuffer(FALSE);
  701.     globalLightRadius = radius;
  702.     runner = LISTOF(lights);
  703.     while (runner)
  704.     {
  705.     ObjPtr light;
  706.  
  707.     DrawObject(runner -> thing);
  708.     runner = runner -> next;
  709.     }
  710.  
  711.     zbuffer(TRUE);
  712. #endif
  713. }
  714.  
  715. static ObjPtr DeleteLightIcon(icon)
  716. ObjPtr icon;
  717. /*Deletes a light object associated with an icon*/
  718. {
  719.     ObjPtr space, contents;
  720.     ObjPtr repObj;
  721.  
  722.     repObj = GetObjectVar("DeleteLightIcon", icon, REPOBJ);
  723.     if (!repObj)
  724.     {
  725.     return ObjFalse;
  726.     }
  727.  
  728.     space = GetVar(icon, SPACE);
  729.     if (!space)
  730.     {
  731.     return ObjFalse;
  732.     }
  733.  
  734.     SetVar(repObj, SPACE, NULLOBJ);
  735.     contents = GetListVar("DeleteVisObjectIcon", space, LIGHTS);
  736.     if (!contents)
  737.     {
  738.     return ObjFalse;
  739.     }
  740.     DeleteFromList(contents, repObj);
  741.     ImInvalid(space);
  742.     return ObjTrue;
  743. }
  744.  
  745. static ObjPtr MakeLightAppearance(light)
  746. ObjPtr light;
  747. /*Dummy make for light appearance*/
  748. {
  749.     SetVar(light, APPEARANCE, ObjTrue);
  750.     ImInvalid(light);
  751.     return ObjTrue;
  752. }
  753.  
  754. void InitLights()
  755. {
  756.     ObjPtr icon;
  757.     ObjPtr list;
  758.  
  759. #ifdef GRAPHICS
  760.     lmdef(DEFLMODEL, 1, 0, lightModel);
  761. #endif
  762.  
  763.     /*Create class of lights*/
  764.     lightClass = NewObject(controllerClass, 0);
  765.     AddToReferenceList(lightClass);
  766.     SetMethod(lightClass, BINDTOSPACE, BindLightToSpace);
  767.     SetMethod(lightClass, NEWCTLWINDOW, ShowLightControls);
  768.     SetVar(lightClass, DOUBLECLICK, NewString(OF_SHOW_CONTROLS));
  769.     SetMethod(lightClass, HIDE, HideLight);
  770.     SetMethod(lightClass, SHOW, ShowLight);
  771.     list = NewList();
  772.     PrefixList(list, NewSymbol(HIDDEN));
  773.     SetVar(lightClass, SNAPVARS, list);
  774.     SetMethod(lightClass, CLONE, CloneLight);
  775.     SetMethod(lightClass, DRAW, DrawLight);
  776.     SetVar(lightClass, CLASSID, NewInt(CLASS_LIGHT));
  777.     DeclareDependency(lightClass, APPEARANCE, SELECTED);
  778.     SetMethod(lightClass, APPEARANCE, MakeLightAppearance);
  779.  
  780.     icon = NewIcon(0, 0, ICONLIGHTS, "Light");
  781.     SetVar(icon, HELPSTRING,
  782.     NewString("This icon represents a light.  When this icon is selected, \
  783. a ray showing the direction and color of the light will appear in the space.  \
  784. You can rotate the light by pressing and dragging in the space with the center \
  785. mouse button.  You can show the controls for the light, such as the brightness and \
  786. color, by selecting it and choosing the Show Controls item in the Object menu.\n\
  787. \nYou can drag the light icon to the corral of another visualization \
  788. window to have it illuminate that space as well.  A space can hold up to eight lights.  \
  789. The easiest way to add additional lights is to select a light and choose Duplicate from \
  790. the Object menu.")); 
  791.     SetMethod(icon, DELETEICON, DeleteLightIcon);
  792.     SetMethod(lightClass, DUPLICATE, DuplicateSpaceObject);
  793.     SetMethod(lightClass, DELETE, DeleteObject);
  794.     SetVar(lightClass, DEFAULTICON, icon);
  795.     SetVar(lightClass, NAME, NewString("Light"));
  796. }
  797.  
  798. void KillLights()
  799. {
  800.     DeleteThing(lightClass);
  801. }
  802.